<!DOCTYPE html
        PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<textarea id="code">
    var Test = function(){//aaaa for;bbb for;;;;
    this.name = 'xling';var version = '1.0';//for(i=0;i<2;i++)\n

    var str = 'for(i=0;i<10;i++){'
    str = 'while(true) bb();'

    if(true)
    bb()
    this.doSomething = function(){
    alert('here');
    for(i=0;i<10;i++){/*for;*/
    aa();
    }
    }
    } ;
    var aa = {};
    aa
    bb
</textarea>
<input type="button" value="格式" onclick="geshi()"/>

<div id="highlight"></div>
<script type="text/javascript">
    String.prototype.trim = function() {
        return this.replace(/(^\s*)|(\s*$)/g, "");
    }
    String.prototype.repeat = function(time) {
        if (time <= 0) return '';
        return (new Array(time + 1)).join(this);
    }

    var breakSemicolon = function() {
        var commentpos = arguments[2].indexOf('//');
        if (commentpos != -1 && commentpos < arguments[1])
            return ';';
        
        var arr = arguments[2].substr(0, arguments[1]).split(';');
        var len = arr.length ;

        //除去 for(;;)
        if (/for\s*\(/.test(arr[len]) || /for\s*\(/.test(arr[len - 1]) || /for\s*\(/.test(arr[len - 2])) {
            return ';';
        } else {
            return ';\n';
        }
    }


    var geshi = function() {
        var source = document.getElementById('code').value.trim();
        //source = source.replace(/({|})/ig,'$1\n');
        source = source.replace(/({|})([^'"\n])/ig, '$1\n$2');
        source = source.replace(/;/g,breakSemicolon);
        var lines = source.split('\n'); // 以换行折分
        var goal = [];
        var i,t;
        for (i = 0; i < lines.length; i++) {
            lines[i] = lines[i].trim();
            if (lines[i] == '') {
                continue;
            }
            t = lines[i].replace(/((\/\/)|(\/\*))/, '\n$1').split('\n');//把子行 以单行注释拆分
            goal = goal.concat(t);
        }
        delete lines;
        var indent = 0;

        var minusIndent = function() {
            indent --;
            if (indent < 0) indent = 0;
        }

        for (i = 0; i < goal.length; i++) {
            //以 } 或 }; 结尾
            if (/}\s*;?$/.test(goal[i])) {
                minusIndent();
            }
            //非 ; { } ( ) */ //  结尾
            //if(goal[i]!= '' && !(/[;|{|}|(\(.*\))|(\*\/)]$/.test(goal[i])) && (!/^\/\//.test(goal[i]))){
            if (goal[i] != '' && !(/[;|{|}|\*\/]$/.test(goal[i])) && (!/^[\/\/|if|for|while|do]/.test(goal[i]))) {
                goal[i] = goal[i] + ';';
            }
            goal[i] = '&nbsp;'.repeat(indent * 4) + goal[i];
            //如  果是以 { 结尾，或以 for(..) while(..) ... 结尾
            //由于上面加了 &nbsp; 所以，判断 开头的时候，要加上 &nbsp;
            if (/{$/.test(goal[i]) || /^(\&nbsp;)*[(for|while|if|do)].*\)$/.test(goal[i])) {
                indent ++;
            }
            //如果前一行 是 for(..) while(..) ....
            //如果后一行是 })(..)
            if (/^(&nbsp;)*[(for|while|if|do)].*\)$/.test(goal[i - 1]) || /^}\s*\)\s*\(.*\)\s*;?/.test(goal[ i + 1]))
                minusIndent();
        }
        document.getElementById('highlight').innerHTML = '<div>' + goal.join('</div><div>') + '</div>';
    }
        //var ttt = ['a',[1,2,['e','f','g'],3],'b','c']
</script>
</body>
</html>